//
//  MLThemeManager.m
//  MSHandbook
//
//  Created by molon on 14/11/22.
//  Copyright (c) 2014年 molon. All rights reserved.
//

#import "MLThemeManager.h"
#import "UIColor+MLKit.h"

@interface MLThemeManager()

/**
 *  颜色值的字符串
 */
@property (nonatomic, strong) NSDictionary *colorStrings;
/**
 *  颜色实体，当前加载的，这个玩意用strong weak
 */
@property (nonatomic, strong) NSMapTable *colors;

/**
 *  需要应用皮肤的目标记录，weak保存
 */
@property (nonatomic, strong) NSHashTable *targets;

@property (nonatomic, weak) id applicationDidReceiveMemoryWarningObserver;

@end

@implementation MLThemeManager

+ (instancetype)manager {
    static id _sharedInstance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _sharedInstance = [[self class] new];
    });
    return _sharedInstance;
}

#pragma mark - life cycle
- (instancetype)init
{
    self = [super init];
    if (self) {
        //其实这里不是台有必要，因为本身就是weak保存的map
        self.applicationDidReceiveMemoryWarningObserver = [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidReceiveMemoryWarningNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification * __unused notification) {
            [self.colors removeAllObjects];
        }];
        
        NSAssert(![self isMemberOfClass:[MLThemeManager class]], @"MLThemeManager类必须继承才可使用");
    }
    return self;
}

- (void)dealloc
{
    [[NSNotificationCenter defaultCenter]removeObserver:self.applicationDidReceiveMemoryWarningObserver];
}


- (void)appLauched
{
    /**
     *  激活下默认皮肤
     */
    self.themeName = nil;
}

#pragma mark - getter
- (NSMapTable *)colors
{
	if (!_colors) {
		_colors = [NSMapTable strongToWeakObjectsMapTable];
	}
	return _colors;
}

- (NSHashTable *)targets
{
	if (!_targets) {
		_targets = [NSHashTable weakObjectsHashTable];
	}
	return _targets;
}

- (UIColor*)colorForKey:(NSString*)key
{
    UIColor *color = [self.colors objectForKey:key];
    //找map里有没有
    if (color) {
        return color;
    }
    
    id colorString = self.colorStrings[key];
    NSAssert(colorString,@"找不到颜色%@的值", key);
    
    if ([colorString isKindOfClass:[NSString class]]) {
        color = [UIColor colorWithMLString:colorString];
    }else if ([colorString isKindOfClass:[UIColor class]]){ //如果直接是color就拿到手就是了。
        color = colorString;
    }
    NSAssert(color, @"颜色%@的值%@无效",key,colorString);
    [self.colors setObject:color forKey:key];
    
    return color;
}


#pragma mark - setter
- (void)setThemeName:(NSString *)themeName
{
    _themeName = [themeName copy];
    
    //删除缓存
    [self.colors removeAllObjects];
    
    self.colorStrings = [self colorStringDictForThemeName:themeName];
    
    for (id<MLThemeManagerDelegate> delegate in self.targets) {
        if ([delegate respondsToSelector:@selector(applyTheme)]) {
            [delegate applyTheme];
        }
        if ([delegate respondsToSelector:@selector(applyThemeExtra)]) {
            [delegate applyThemeExtra];
        }
    }
    
    //设置系统的一些app
    [self updateAppearanceStylesWithThemeName:themeName];
    
    //WARNING:测试发现，当前不在window里显示的那些Appearance，会延迟更新，所以切换主题的功能按钮，请不要放在modal vc里
    
    //整个app的界面重绘下
    for (UIWindow *window in [UIApplication sharedApplication].windows) {
        if ([window.rootViewController respondsToSelector:@selector(setNeedsStatusBarAppearanceUpdate)]) {
            
            [window.rootViewController setNeedsStatusBarAppearanceUpdate];
        }
        
        for (UIView *view in window.subviews) {
            [view removeFromSuperview];
            [window addSubview:view];
        }
        
        CATransition *animation = [CATransition animation];
        animation.duration = 0.5;
        animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
        animation.type = kCATransitionFade;
        [window.layer addAnimation:animation forKey:nil];
    }

}

#pragma mark - delegate
- (void)registerDelegate:(id<MLThemeManagerDelegate>)delegate
{
    if (delegate&&![self.targets containsObject:delegate]) {
        [self.targets addObject:delegate];
    }
}

- (void)unregisterDelegate:(id<MLThemeManagerDelegate>)delegate
{
    if (delegate) {
        [self.targets removeObject:delegate];
    }
}

#pragma mark - other need custom
- (void)updateAppearanceStylesWithThemeName:(NSString*)themeName
{
    //这个类不适宜直接使用，必须继承
    [self doesNotRecognizeSelector:_cmd];
    
}

- (NSDictionary *)colorStringDictForThemeName:(NSString*)themeName
{
    //这个类不适宜直接使用，必须继承
    [self doesNotRecognizeSelector:_cmd];
    
    return nil;
}
@end
